#include <mutex>
#include <iostream>

using namespace std;

// 饿汉式
class Singleton1 {
private:
    // 将其构造和析构成为私有的, 禁止类外构造和析构
    Singleton1() = default;

    ~Singleton1() = default;

private:
    static Singleton1 *instance;

public:
    static Singleton1 *getInstance() {
        return instance;
    }
};

Singleton1 *Singleton1::instance = new Singleton1();

// 线程不安全的懒汉式
class Singleton2 {
private:
    Singleton2() = default;

    ~Singleton2() = default;

private:
    static Singleton2 *instance;

public:
    static Singleton2 *getInstance() {
        if (instance == nullptr) {
            instance = new Singleton2();
        }

        return instance;
    }
};

// 线程安全的懒汉式
class Singleton3 {
private:
    Singleton3() = default;

    ~Singleton3() = default;

private:
    static Singleton3 *instance;

    static pthread_mutex_t mutex;

public:
    static Singleton3 *getInstance() {
        pthread_mutex_lock(&mutex);
        if (instance == nullptr) {
            instance = new Singleton3();
        }
        pthread_mutex_unlock(&mutex);

        return instance;
    }
};

Singleton3 *Singleton3::instance = nullptr;

pthread_mutex_t Singleton3::mutex = PTHREAD_MUTEX_INITIALIZER;

// 线程安全的懒汉式(双检锁)
class Singleton4 {
private:
    Singleton4() = default;

    ~Singleton4() = default;

    // 删除拷贝构造和赋值构造成函数, 禁止类外拷贝和赋值
    Singleton4(const Singleton4 &) = delete;

    const Singleton4 &operator=(const Singleton4 &) = delete;

private:
    // 唯一单实例对象指针
    static Singleton4 *instance;

    static pthread_mutex_t mutex;

public:
    static Singleton4 *getInstance() {
        if (instance == nullptr) {
            pthread_mutex_lock(&mutex);
            if (instance == nullptr) {
                new Singleton4();
            }
            pthread_mutex_unlock(&mutex);
        }

        return instance;
    }
};

Singleton4 *Singleton4::instance = nullptr;

pthread_mutex_t Singleton4::mutex = PTHREAD_MUTEX_INITIALIZER;

// 使用静态成员变量实现单例
class Singleton5 {
private:
    Singleton5() = default;

    ~Singleton5() = default;

    Singleton5(const Singleton5 &) = delete;

    const Singleton5 &operator=(const Singleton5 &) = delete;

public:
    static Singleton5 *getInstance() {
        static Singleton5 *instance = new Singleton5();

        return instance;
    }
};

// C++ 11 使用 std::call_once 函数实现单例
class Singleton6 {
private:
    Singleton6() = default;

    ~Singleton6() = default;

    Singleton6(const Singleton6 &) = delete;

    const Singleton6 &operator=(const Singleton6 &) = delete;

private:
    static once_flag flag;

    static Singleton6 *instance;

public:
    static Singleton6 *getInstance() {
        call_once(flag, [&] {
            instance = new Singleton6();
        });

        return instance;
    }
};

Singleton6 *Singleton6::instance = nullptr;